#ifndef __BFX_H__
#define __BFX_H__

#include "common.h"

/* Holds maximum length of 8-bit data */
#define BFX_MAX_LENGTH_8BIT ((uint8)8)
/* Holds maximum length of 16-bit data */
#define BFX_MAX_LENGTH_16BIT ((uint8)16)
/* Holds maximum length of 32-bit data */
#define BFX_MAX_LENGTH_32BIT ((uint8)32)
/* Holds maximum length of 64-bit data */

void Bfx_SetBit_u8u8(uint8 *Data, uint8 BitPn);
void Bfx_SetBit_u16u8(uint16 *Data, uint8 BitPn);
void Bfx_SetBit_u32u8(uint32 *Data, uint8 BitPn);

void Bfx_ClrBit_u8u8(uint8 *Data, uint8 BitPn);
void Bfx_ClrBit_u16u8(uint16 *Data, uint8 BitPn);
void Bfx_ClrBit_u32u8(uint32 *Data, uint8 BitPn);

boolean Bfx_GetBit_u8u8_u8(uint8 Data, uint8 BitPn);
boolean Bfx_GetBit_u16u8_u8(uint16 Data, uint8 BitPn);
boolean Bfx_GetBit_u32u8_u8(uint32 Data, uint8 BitPn);

void Bfx_SetBits_u8u8u8u8(uint8 *Data, uint8 BitStartPn, uint8 BitLn,
                          uint8 Status);
void Bfx_SetBits_u16u8u8u8(uint16 *Data, uint8 BitStartPn, uint8 BitLn,
                           uint8 Status);
void Bfx_SetBits_u32u8u8u8(uint32 *Data, uint8 BitStartPn, uint8 BitLn,
                           uint8 Status);

uint8 Bfx_GetBits_u8u8u8_u8(uint8 Data, uint8 BitStartPn, uint8 BitLn);
uint16 Bfx_GetBits_u16u8u8_u16(uint16 Data, uint8 BitStartPn, uint8 BitLn);
uint32 Bfx_GetBits_u32u8u8_u32(uint32 Data, uint8 BitStartPn, uint8 BitLn);

void Bfx_SetBitMask_u8u8(uint8 *const Data, const uint8 Mask);
void Bfx_SetBitMask_u16u16(uint16 *const Data, const uint16 Mask);
void Bfx_SetBitMask_u32u32(uint32 *const Data, const uint32 Mask);

void Bfx_ClrBitMask_u8u8(uint8 *const Data, const uint8 Mask);
void Bfx_ClrBitMask_u16u16(uint16 *const Data, const uint16 Mask);
void Bfx_ClrBitMask_u32u32(uint32 *const Data, const uint32 Mask);

boolean Bfx_TstBitMask_u8u8_u8(const uint8 Data, const uint8 Mask);
boolean Bfx_TstBitMask_u16u16_u8(const uint16 Data, const uint16 Mask);
boolean Bfx_TstBitMask_u32u32_u8(const uint32 Data, const uint32 Mask);

boolean Bfx_TstBitLnMask_u8u8_u8(const uint8 Data, const uint8 Mask);
boolean Bfx_TstBitLnMask_u16u16_u8(const uint16 Data, const uint16 Mask);
boolean Bfx_TstBitLnMask_u32u32_u8(const uint32 Data, const uint32 Mask);

boolean Bfx_TstParityEven_u8_u8(uint8 Data);
boolean Bfx_TstParityEven_u16_u8(uint16 Data);
boolean Bfx_TstParityEven_u32_u8(uint32 Data);

void Bfx_ToggleBits_u8(uint8 *const Data);
void Bfx_ToggleBits_u16(uint16 *const Data);
void Bfx_ToggleBits_u32(uint32 *const Data);

void Bfx_ToggleBitMask_u8u8(uint8 *const Data, const uint8 Mask);
void Bfx_ToggleBitMask_u16u16(uint16 *const Data, const uint16 Mask);
void Bfx_ToggleBitMask_u32u32(uint32 *const Data, const uint32 Mask);

void Bfx_ShiftBitRt_u8u8(uint8 *const Data, const uint8 ShiftCnt);
void Bfx_ShiftBitRt_u16u8(uint16 *const Data, const uint8 ShiftCnt);
void Bfx_ShiftBitRt_u32u8(uint32 *const Data, const uint8 ShiftCnt);

void Bfx_ShiftBitLt_u8u8(uint8 *const Data, const uint8 ShiftCnt);
void Bfx_ShiftBitLt_u16u8(uint16 *const Data, const uint8 ShiftCnt);
void Bfx_ShiftBitLt_u32u8(uint32 *const Data, const uint8 ShiftCnt);

void Bfx_RotBitRt_u8u8(uint8 *const Data, const uint8 ShiftCnt);
void Bfx_RotBitRt_u16u8(uint16 *const Data, const uint8 ShiftCnt);
void Bfx_RotBitRt_u32u8(uint32 *const Data, const uint8 ShiftCnt);

void Bfx_RotBitLt_u8u8(uint8 *const Data, const uint8 ShiftCnt);
void Bfx_RotBitLt_u16u8(uint16 *const Data, const uint8 ShiftCnt);
void Bfx_RotBitLt_u32u8(uint32 *const Data, const uint8 ShiftCnt);

void Bfx_CopyBit_u8u8u8u8(uint8 *DestinationData, uint8 DestinationPosition,
                          uint8 SourceData, uint8 SourcePosition);
void Bfx_CopyBit_u16u8u16u8(uint16 *DestinationData, uint8 DestinationPosition,
                            uint16 SourceData, uint8 SourcePosition);
void Bfx_CopyBit_u32u8u32u8(uint32 *DestinationData, uint8 DestinationPosition,
                            uint32 SourceData, uint8 SourcePosition);

void Bfx_PutBits_u8u8u8u8(uint8 *Data, uint8 BitStartPn, uint8 BitLn,
                          uint8 Pattern);
void Bfx_PutBits_u16u8u8u16(uint16 *Data, uint8 BitStartPn, uint8 BitLn,
                            uint16 Pattern);
void Bfx_PutBits_u32u8u8u32(uint32 *Data, uint8 BitStartPn, uint8 BitLn,
                            uint32 Pattern);

void Bfx_PutBitsMask_u8u8u8(uint8 *const Data, const uint8 Pattern,
                            const uint8 Mask);
void Bfx_PutBitsMask_u16u16u16(uint16 *const Data, const uint16 Pattern,
                               const uint16 Mask);
void Bfx_PutBitsMask_u32u32u32(uint32 *const Data, const uint32 Pattern,
                               const uint32 Mask);

void Bfx_PutBit_u8u8u8(uint8 *Data, uint8 BitPn, boolean Status);
void Bfx_PutBit_u16u8u8(uint16 *Data, uint8 BitPn, boolean Status);
void Bfx_PutBit_u32u8u8(uint32 *Data, uint8 BitPn, boolean Status);

#endif